
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {

    /**
     * 第一遍
     * @param nums
     * @return
     */
//    public List<List<Integer>> threeSum(int[] nums) {
//        int len = nums.length;
//        Arrays.sort(nums);
//        List<List<Integer>> ans = new ArrayList<List<Integer>>();
//
//        if (nums == null || len < 3) return ans;
//
//        // 枚举a
//        for (int i = 0; i < len; i++) {
//            // 如果当前数字大于0，则三数之和一定大于0，因为该数组已经排序，第一个元素必须要负数
//            if (nums[i] > 0) break;
//            // 去重：因为总共3个数字之和，满足下面的条件可能为：-2，1，1；在此情况下会出现重复
//            if (i > 0 && nums[i] == nums[i-1]) continue;
//
//            // 下一个
//            int L = i + 1;
//            // 尾部
//            int R = len - 1;
//            while (L < R) {
//                int sum = nums[i] + nums[L] + nums[R];
//                if (sum == 0) {
//                    ans.add(Arrays.asList(nums[i], nums[L], nums[R]));
//                    while (L < R && nums[L] == nums[L + 1]) L++;
//                    while (L < R && nums[R] == nums[R - 1]) R--;
//                    L++;
//                    R--;
//                } else if (sum < 0) {
//                    // 小于0，还需要向后加
//                    L++;
//                } else {
//                    // 大于0，还需要前后加
//                    R--;
//                }
//            }
//        }
//        return ans;
//    }


    /**
     * 第二遍
     * @param nums
     * @return
     */
//    public List<List<Integer>> threeSum(int[] nums) {
//        int len = nums.length;
//        Arrays.sort(nums);
//        List<List<Integer>> ans = new ArrayList<List<Integer>>();
//        if (nums == null || len < 3) return ans;
//
//        // 枚举
//        for (int i = 0; i < len; i++) {
//            if (nums[i] > 0) break;
//            // 去重
//            if (i > 0 && nums[i] == nums[i - 1]) continue;
//
//            // 下一个
//            int L = i + 1, R = len - 1;
//            while (L < R) {
//                int sum = nums[i] + nums[L] + nums[R];
//                if (sum == 0) {
//                    ans.add(Arrays.asList(nums[i], nums[L], nums[R]));
//                    while (L < R && nums[L] == nums[L + 1]) L++;
//                    while (L < R && nums[R] == nums[R - 1]) R--;
//                    L++;
//                    R--;
//                } else if (sum > 0) {
//                    R--;
//                } else {
//                    L++;
//                }
//            }
//        }
//        return ans;
//    }


    /**
     * 第三遍 2/27
     * @param nums
     * @return
     */
    public List<List<Integer>> threeSum(int[] nums) {
        int len = nums.length;
        // 排序
        Arrays.sort(nums);
        ArrayList<List<Integer>> ans = new ArrayList<List<Integer>>();
        if (nums == null || len < 3) return ans;

        // 枚举
        for (int i = 0; i < len; i++) {
            if (nums[i] > 0) break;

            // 去重
            if (i > 0 && nums[i] == nums[i - 1]) continue;

            // 双指针
            int L = i + 1, R = len - 1;
            while (L < R) {
                int sum = nums[i] + nums[L] + nums[R];
                if (sum == 0) {
                    ans.add(Arrays.asList(nums[i], nums[L], nums[R]));
                    while (L < R && nums[L] == nums[L+1]) L++;
                    while (L < R && nums[R] == nums[R-1]) R--;
                    L++;
                    R--;
                } else if (sum > 0) {
                    R--;
                } else {
                    L++;
                }
            }
        }
        return ans;
    }
}
//leetcode submit region end(Prohibit modification and deletion)
